/*
 * Copyright (c) 2021 FuZhou LOCKZHINER Electronic Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

#include "ohos_init.h"
#include "los_task.h"
#include "e53_temperature_measurement.h"
#include "lcd.h"
#include "picture.h"
#include "lcd_font.h"
#include "com_msg.h"
#include "e53_com.h"

static char *str_state[] = {
    "无人",
    "正常",
    "异常",
};

tmfifo_t           tmfifo = {0};
static lcd_param_t lcd = {.dir = 0, .f_color = LCD_LBBLUE, .b_color = LCD_WHITE, .f_size = 32, .start_line = IMAGE_H_SIEZ};
e53_tm_data_t      g_tm_data = {0};

/***************************************************************
* 函数名称: lcd_reset
* 说    明: lcd显示复位
* 参    数: lcd_param_t lcd
* 返 回 值: 无
***************************************************************/
static void lcd_reset(lcd_param_t lcd)
{
    lcd_fill(0, 0, lcd.w, lcd.h, lcd.b_color);
    // lcd_show_picture((lcd.w - IMAGE_W_SIEZ) / 2, 0, IMAGE_W_SIEZ, IMAGE_H_SIEZ, gImage_lingzhi);
    lcd_show_picture(65, 0, 190, 38, gImage_EurAsiaUni);
    lcd_draw_line(0, 40, 320, 40, lcd.f_color);
}

/***************************************************************
* 函数名称: lcd_welcome
* 说    明: lcd显示欢迎界面
* 参    数: lcd_param_t lcd
* 返 回 值: 无
***************************************************************/
static void lcd_welcome(lcd_param_t lcd)
{
    lcd_reset(lcd);
    Printf_Lcd(0, lcd.start_line + lcd.f_size * 0, lcd.f_color, lcd.b_color, lcd.f_size, E_LCD_SCREEN_ALIGN_MID_NOP, "欢迎使用");
    int len = get_str_size("OpenHarmony", lcd.f_size);
    lcd_left_move(lcd.w - len, LCD_LEFT_MOVE_EDN(lcd.w, "OpenHarmony", lcd.f_size), lcd.start_line + lcd.f_size * 1, lcd.f_color, lcd.b_color, lcd.f_size, len, "OpenHarmony");
    lcd_right_move(0, LCD_RIGHT_MOVE_EDN(lcd.w, "红外测温", lcd.f_size), lcd.start_line + lcd.f_size * 2, lcd.f_color, lcd.b_color, lcd.f_size, "红外测温");
    LOS_Msleep(1000);
    lcd_reset(lcd);
}

/***************************************************************
* 函数名称: send_data
* 说    明: 数据发送，将g_tm_data内数据发送
* 参    数: 无
* 返 回 值: 无
***************************************************************/
static void send_data(void)
{
    msg_smart_medical_report_tm_t tm   = {0};
    e53_tm_data_t                *data = &g_tm_data;
    
    tm.tm_v   = data->flag == 0 ? 0 : 1;
    tm.tm     = data->temperature * 100;
    send_e53_data(1, &tm);
}

/***************************************************************
* 函数名称: display_date
* 说    明: lcd显示数据
* 参    数: lcd_param_t lcd, e53_tm_data_t data
* 返 回 值: 无
***************************************************************/
static void display_date(lcd_param_t lcd, e53_tm_data_t data)
{
    FifoPutTm(&tmfifo, &data);
    memcpy(&g_tm_data, &data, sizeof(e53_tm_data_t));
    send_data();
    
#define H_SIZE 48
#define STR_TITLE   "温度:"
#define STR_TITLE1  "状态:"
#define STR_PARAM   "%.1f°C"
#define STR_PARAM1  "%s"
#define STR_PARAM2  "------"
    uint16_t fc = lcd.f_color;
    static e53_tm_data_t l = {0};
    
    if (data.flag == 2) {
        fc = LCD_RED;
    } else if (data.flag == 1) {
        fc = LCD_GREEN;
    }
    
    Printf_Lcd(0, lcd.start_line + lcd.f_size * 1, lcd.f_color, lcd.b_color, lcd.f_size, E_LCD_SCREEN_ALIGN_LEFT, STR_TITLE);
    if (data.flag != 0) {
        Printf_Lcd(get_str_size(STR_TITLE, lcd.f_size), lcd.start_line + lcd.f_size * 1, fc, lcd.b_color, lcd.f_size,
                   E_LCD_SCREEN_ALIGN_NONE_RIGHT_SURPLUS_NOP, STR_PARAM, data.temperature);
        l.temperature = data.temperature;
    } else if (l.temperature > 34) {
        Printf_Lcd(get_str_size(STR_TITLE, lcd.f_size), lcd.start_line + lcd.f_size * 1, LCD_BLACK, lcd.b_color, lcd.f_size,
                   E_LCD_SCREEN_ALIGN_NONE_RIGHT_SURPLUS_NOP, STR_PARAM, l.temperature);
    }
    
    if (data.flag == 2) {
        lcd_show_picture(lcd.w - H_SIZE, lcd.start_line + lcd.f_size * 3, H_SIZE, H_SIZE, gImage_hot_temp);
    } else if (data.flag == 1) {
        lcd_show_picture(lcd.w - H_SIZE, lcd.start_line + lcd.f_size * 3, H_SIZE, H_SIZE, gImage_btemp);
    } else {
        lcd_show_picture(lcd.w - H_SIZE, lcd.start_line + lcd.f_size * 3, H_SIZE, H_SIZE, gImage_nobody);
        static int dp = 0;
        if (dp == 0) {
            if (data.temperature < 20) Printf_Lcd(get_str_size(STR_TITLE, lcd.f_size), lcd.start_line + lcd.f_size * 1, lcd.f_color, lcd.b_color, lcd.f_size,
                                                      E_LCD_SCREEN_ALIGN_NONE_RIGHT_SURPLUS_NOP, STR_PARAM2);
            dp = 1;
        }
    }
    Printf_Lcd(0, lcd.start_line + lcd.f_size * 3, lcd.f_color, lcd.b_color, H_SIZE, E_LCD_SCREEN_ALIGN_LEFT, STR_TITLE1);
    Printf_Lcd(get_str_size(STR_TITLE1, H_SIZE), lcd.start_line + lcd.f_size * 3, fc, lcd.b_color, H_SIZE,
               E_LCD_SCREEN_ALIGN_NONE, STR_PARAM1, str_state[data.flag]);
}

/***************************************************************
* 函数名称: display_init
* 说    明: lcd显示初始化
* 参    数: lcd_param_t *lcd, char *name
* 返 回 值: 无
***************************************************************/
static void display_init(lcd_param_t *lcd, char *name)
{
    printf("\n\n%s\n", __FUNCTION__);
    lcd->w = g_lcd_size.w;
    lcd->h = g_lcd_size.h;
    lcd_welcome(*lcd);
    Printf_Lcd(0, lcd->start_line + lcd->f_size * 0, lcd->f_color, lcd->b_color, lcd->f_size, E_LCD_SCREEN_ALIGN_MID_NOP, name);
}

/***************************************************************
* 函数名称: e53_tm_thread
* 说    明: 红外测温模块例程
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void e53_tm_thread(void *args)
{
    unsigned int ret = LZ_HARDWARE_SUCCESS;
    e53_tm_data_t data = {0};
    int cnt = 0;
    float last = 0, state;
    static int init = 0;
    
    if (init == 0) {
        display_init(&lcd, "红外测温");
        init = 1;
    } else {
        lcd_reset(lcd);
        Printf_Lcd(0, lcd.start_line + lcd.f_size * 0, lcd.f_color, lcd.b_color, lcd.f_size, E_LCD_SCREEN_ALIGN_MID_NOP, "红外测温");
    }
    display_date(lcd, data);
    e53_tm_init();
    
    while (1) {
        if (SUCCESS == e53_tm_read_data(&data.temperature, &state)) {
            printf("temperature:%0.1f, l:%.1f, f:%.1f, %s\n", data.temperature, last, state, str_state[data.flag]);
            if (data.temperature > 37.5) {
                cnt = 0;
                data.flag = 2;
                tm_light_set_status(ON);
                LOS_Msleep(100);
                tm_light_set_status(OFF);
                // last = data.temperature;
            } else if (data.temperature < state) {
                //异常值延缓显示
                if ((++cnt) % 3 == 0) {
                    data.flag = 0;
                    tm_light_set_status(OFF);
                } else {
                    data.temperature = last != 0 ? last : data.temperature;
                }
            } else {
                cnt = 0;
                data.flag = 1;
                tm_light_set_status(ON);
                last = data.temperature;
            }
            // printf("temperature:%0.1f\n", data.temperature);
            display_date(lcd, data);
        } else {
            if ((++cnt) % 3 == 0) {
                data.flag = 0;
                tm_light_set_status(OFF);
            } else {
                data.temperature = last != 0 ? last : data.temperature;
            }
            printf("temperature err\n");
        }
        LOS_Msleep(1000);
    }
}

void e53_tm_example()
{
    unsigned int ret = LOS_OK;
    unsigned int thread_id;
    TSK_INIT_PARAM_S task = {0};
    FifoInitTm(&tmfifo);
    
    task.pfnTaskEntry = (TSK_ENTRY_FUNC)e53_tm_thread;
    task.uwStackSize = 10240;
    task.pcName = "e53_tm_thread";
    task.usTaskPrio = 2;
    ret = LOS_TaskCreate(&thread_id, &task);
    if (ret != LOS_OK) {
        printf("Falied to create e53_tm_thread ret:0x%x\n", ret);
        return;
    }
}
